package ve.com.wayoyo.wuml_case.DibujoDiagramas;

import java.util.ArrayList;

import ve.com.wayoyo.wuml_case.Painter;
import ve.com.wayoyo.wuml_case.Exceptions.TituloVacioExecption;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.widget.TextView;

public abstract class Diagrama {

	static final int scrollBarSize = 50;

	protected String Nombre;
	protected String Tipo;
	private String root;
	protected Componente SelectedItem;
	protected CompConector _SelectedConector;
	protected int lastIdGiven = 0;
	protected ArrayList<Componente> _components = new ArrayList<Componente>();
	protected Point _topLeft;
	protected Point _botRight;
	protected Point BottomScrollBarPlace = new Point(0, 0);
	protected Point LeftScrollBarPlace = new Point(0, 0);
	private RectF VerticalScrollBar = new RectF();
	private RectF HorizontalScrollBar = new RectF();
	private RectF ZoomHelperSquare = null;
	private String Nota;

	protected boolean _showHelp = true;

	protected boolean _showTutorial = true;
	protected int _tutorialStage = 1;
	
	public Diagrama(){
		super();
		actualizarBordes();
	}
	
	public void setLastIdGiven(int lastIdGiven) {
		this.lastIdGiven = lastIdGiven;
	}

	public CompConector get_SelectedConector() {
		return _SelectedConector;
	}

	public Componente getSelectedItem() {
		return SelectedItem;
	}

	public String getNombre() {
		return Nombre;
	}

	public void setNombre(String nombre) {
		Nombre = nombre;
	}

	public String getTipo() {
		return Tipo;
	}

	public void setTipo(String tipo) {
		Tipo = tipo;
	}

	public void AgregarComponente(Componente nuevo) {
		if (nuevo.ID == 0) {
			nuevo.setID(this.get_lastIdGiven());			
		}
		_components.add(nuevo);
	}
	
	public int get_lastIdGiven(){
		return lastIdGiven += 1;
	}
	
	public void EliminarComponente(Componente viejo) {
		if (!(viejo instanceof CompSubEntidad))
			_components.remove(viejo);
		else {
			for (Componente component : _components) {
				if ((component instanceof CompEntidad)
						&& (((CompEntidad) component).get_subEntidades()
								.contains(viejo))) {
					component.set_height(component.get_height()
							- viejo.get_height());
					component.actualizarPuntoCentral();
					component.actualizarAchorsPoints();
					((CompEntidad) component).get_subEntidades().remove(viejo);
					break;
				}
			}
		}
		resetFocus();
		SelectedItem = null;
	}

	public Componente getComponenteById(int id) {
		for (Componente value : _components) {
			if (value.getID() == id)
				return value;
		}
		return null;
	}

	public abstract void moverItemSeleccionado(int distX, int distY);

	public abstract void Dibujar(Canvas c, int offSetX, int offSetY,
			float GlobalScale);

	public abstract int checkOnTouch(Point touchPoint, String type);

	public abstract void resetFocus();

	public abstract boolean validarNombre(String nuevo)
			throws TituloVacioExecption;

	public int getDiagramHeight() {
		int minValueY = Integer.MAX_VALUE;
		int maxValueY = Integer.MIN_VALUE;
		for (Componente value : _components) {
			if (value.getAnchor().y <= minValueY) {
				minValueY = value.getAnchor().y;
			}
			if ((value.getAnchor().y + value.get_height()) > maxValueY) {
				maxValueY = (int) (value.getAnchor().y + value.get_height());
			}
		}
		return Math.abs(maxValueY - minValueY);
	}

	public int getDiagramWidth() {
		int minValueX = Integer.MAX_VALUE;
		int maxValueX = Integer.MIN_VALUE;
		for (Componente value : _components) {
			if (value.getAnchor().x <= minValueX) {
				minValueX = value.getAnchor().x;
			}
			if ((value.getAnchor().x + value.get_height()) > maxValueX) {
				maxValueX = (int) (value.getAnchor().x + value.get_width());
			}
		}
		return Math.abs(maxValueX - minValueX);
	}

	public int getDiagramXoffSet() {
		int minValueX = Integer.MAX_VALUE;
		for (Componente value : _components) {
			if (value.getAnchor().x <= minValueX) {
				minValueX = value.getAnchor().x;
			}
		}
		return -1 * minValueX;
	}

	public int getDiagramYoffSet() {
		int minValueY = Integer.MAX_VALUE;
		for (Componente value : _components) {
			if (value.getAnchor().y <= minValueY) {
				minValueY = value.getAnchor().y;
			}
		}
		return -1 * minValueY;
	}

	public String generarDOM() {
		String _nota = "";
		if (Nota != null)
			_nota = Nota;
		String DOM = "<Diagrama Nombre=\"" + Nombre + "\" Tipo=\"" + Tipo
				+ "\" UltimoID=\"" + lastIdGiven + "\" Nota=\"" + _nota + "\">\n";
		for (Componente value : _components) {
			DOM = DOM + value.generarDOM();
		}
		for (Componente value : _components) {
			DOM = DOM + value.getConectorsDOM();
		}
		DOM = DOM + "</Diagrama>";
		return DOM;
	}

	public ArrayList<Componente> get_components() {
		return _components;
	}

	public String getRoot() {
		return root;
	}

	public void setRoot(String root) {
		this.root = root;
	}

	private Point getTopLeftPoint() {
		Point resultado = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
		if (_components.size() == 0) {
			resultado.set(0, 0);
		} else {
			for (Componente val : _components) {
				if (val.getAnchor().x < resultado.x) {
					resultado.set(val.getAnchor().x, resultado.y);
				}
				if (val.getAnchor().y < resultado.y) {
					resultado.set(resultado.x, val.getAnchor().y);
				}
			}
		}
		return resultado;
	}

	private Point getBotRightPoint() {
		Point resultado = new Point(0, 0);
		for (Componente val : _components) {
			if (val.getAnchor().x + val.get_width() > resultado.x) {
				resultado.set((int) (val.getAnchor().x + val.get_height()),
						resultado.y);
			}
			if (val.getAnchor().y + val.get_height() > resultado.y) {
				resultado.set(resultado.x,
						(int) (val.getAnchor().y + val.get_height()));
			}
		}
		return resultado;
	}

	public void actualizarBordes() {
		_topLeft = getTopLeftPoint();
		_botRight = getBotRightPoint();
	}

	public void dibujarScrollBars(Canvas c, int offSetX, int offSetY,
			float GlobalScale) {

		// Horizontal ScrollBar
		int maxOffsetX = (int) ((c.getWidth() / GlobalScale) - _topLeft.x);
		int minOffsetx = -_botRight.x;
		int D1 = maxOffsetX - minOffsetx;
		int D2 = (c.getWidth() - scrollBarSize);
		BottomScrollBarPlace.x = (((offSetX - minOffsetx) * D2) / D1)
				+ (scrollBarSize / 2);
		BottomScrollBarPlace.y = c.getHeight() - 5;
		HorizontalScrollBar.set(BottomScrollBarPlace.x - (scrollBarSize / 2),
				BottomScrollBarPlace.y, BottomScrollBarPlace.x
						+ (scrollBarSize / 2), BottomScrollBarPlace.y - 8);
		HorizontalScrollBar.sort();
		c.drawRoundRect(HorizontalScrollBar, 3, 3, Painter.getInstancia()
				.getScrollBarPaint());
		// c.drawCircle(BottomScrollBarPlace.x, BottomScrollBarPlace.y, 10,
		// Painter.getInstancia().getDefaultBorderPaint());

		// Vertical ScrollBar
		int maxOffsetY = (int) (c.getHeight() / GlobalScale - _topLeft.y);
		int minOffsetY = -_botRight.y;
		D1 = maxOffsetY - minOffsetY;
		D2 = (c.getHeight() - (scrollBarSize));
		LeftScrollBarPlace.y = (((offSetY - minOffsetY) * D2) / D1)
				+ (scrollBarSize / 2);
		LeftScrollBarPlace.x = c.getWidth() - 5;
		VerticalScrollBar.set(LeftScrollBarPlace.x - 8, LeftScrollBarPlace.y
				- (scrollBarSize / 2), LeftScrollBarPlace.x,
				LeftScrollBarPlace.y + (scrollBarSize / 2));
		c.drawRoundRect(VerticalScrollBar, 3, 3, Painter.getInstancia()
				.getScrollBarPaint());
		// c.drawCircle(LeftScrollBarPlace.x, LeftScrollBarPlace.y, 10,
		// Painter.getInstancia().getDefaultBorderPaint());

	}

	public void dibujarZoomGuide(Canvas c, float GlobalScale) {

		if (ZoomHelperSquare == null) {
			ZoomHelperSquare = new RectF();
			ZoomHelperSquare
					.set(c.getWidth() - 145, 10, c.getWidth() - 10, 110);
		}
		c.drawRoundRect(ZoomHelperSquare, 15, 15, Painter.getInstancia()
				.getScrollBarPaint());
		String Zoom = Float.toString(GlobalScale * 100).substring(0, 2);
		if (GlobalScale >= 1) {
			Zoom += "0";
		} else {
			Zoom = " " + Zoom;
		}
		c.drawText(Zoom + "%", c.getWidth() - 135, 75, Painter.getInstancia()
				.getZoomTextPaint());

	}

	public void dibujarAyuda(Canvas c) {
		if (VistaDiagrama.getVista() != null) {
			c.drawBitmap(VistaDiagrama.getVista().BMayuda, 10, 10, new Paint());
		}
	}

	public void disableHelps() {
		_showHelp = false;
	}

	public void disableTutorial() {
		_showTutorial = false;
		_tutorialStage = 5;
	}

	public void dibujarTutorial(Canvas c) {
		if (VistaDiagrama.getVista() != null) {
			if (_components.size() == 1
					&& VistaDiagrama.getVista().getCurrentState() == 0
					&& _tutorialStage == 1) {
				c.drawBitmap(
						VistaDiagrama.getVista().BMtipSeleccionar,
						5,
						c.getHeight()
								- VistaDiagrama.getVista().BMtipSeleccionar
										.getHeight(), new Paint());
			}
			if (_components.size() == 1
					&& VistaDiagrama.getVista().getCurrentState() == 5) {
				if (_tutorialStage == 1) {
					_tutorialStage++;
				}
				if (_tutorialStage < 3) {
					c.drawBitmap(
							VistaDiagrama.getVista().BMtipMover,
							5,
							c.getHeight()
									- VistaDiagrama.getVista().BMtipSeleccionar
											.getHeight(), new Paint());
				}
			}
			if (_components.size() > 1
					&& VistaDiagrama.getVista().getCurrentState() == 5
					|| VistaDiagrama.getVista().getCurrentState() == 4) {
				if (_tutorialStage < 3) {
					_tutorialStage = 3;
				}
				if (_tutorialStage == 3) {
					c.drawBitmap(
							VistaDiagrama.getVista().BMtipConectar,
							5,
							c.getHeight()
									- VistaDiagrama.getVista().BMtipSeleccionar
											.getHeight(), new Paint());
				}
			}
			if (_tutorialStage == 4) {
				if (VistaDiagrama.getVista().getCurrentState() == 5
						|| VistaDiagrama.getVista().getCurrentState() == 4) {
					c.drawBitmap(
							VistaDiagrama.getVista().BMtipSeleccionarConector,
							5,
							c.getHeight()
									- VistaDiagrama.getVista().BMtipSeleccionar
											.getHeight(), new Paint());
				}
				if (VistaDiagrama.getVista().getCurrentState() == 7) {
					_showTutorial = false;
					_tutorialStage = 5;
				}
			}
		}
	}

	public String getNota() {
		return Nota;
	}

	public void setNota(String nota) {
		Nota = nota;
	}

}
